/**
 * 实现功能如下：
 * 1. 按帧读取视频mp4文件
 * 2. 将读取出来的yuv数据，使用crop进行剪切
 * 3. 将剪切之后的数据，保存为yuv文件输出
 */

// const beamcoder = require('beamcoder');
const beamcoder = require('D:\\jscode\\beamcoder-master\\build\\Release\\beamcoder.node');
const {writeData} = require('../../util/util')

async function _getVideoFilter(videoInfo, videoParam) {
    return await beamcoder.filterer({
        filterType: 'video',
        //输入参数
        inputParams: [
            {
                name:'in:0',
                width: videoInfo.width,
                height: videoInfo.height,
                pixelFormat: 'yuv420p',
                sample_aspect_ratio: 0,
                timeBase: [1, 25],
                pixelAspect: [videoInfo.width, videoInfo.height]
            }
        ],
        //输出参数，需要输出为rgba
        outputParams: [
            {
                name:'out:0',
                pixelFormat: 'rgba'
            }
        ],
        filterSpec: `[in:0]crop=w=${videoParam.width}:h=${videoParam.height}:x=0:y=0[out:0]`
    });
}


/**
 * 解析视频帧
 * @param frames
 * @returns {AsyncGenerator<*, {data: Buffer, type: string}, *>}
 */
async function parseVideoFrame(videoFilter, frames) {
    //默认读取出来的视频帧是yuv格式，需要调用filter将其转为rgba
    let filteredData = await videoFilter.filter([{name:'in:0', frames:frames.frames}]);
    let realData = filteredData[0]?.frames[0]?.data[0];
    if (realData) {
        return realData;
    } else {
        console.log(this.sessionId, `fail to receive video frame, data is null`);
    }
}

async function run() {
    let demuxer = await beamcoder.demuxer('D:\\media\\18s_fps25_582x800_48000_mono.mp4');
    let videoDecoder = beamcoder.decoder({params:demuxer.streams[0].codecpar});
    let audioDecoder = beamcoder.decoder({params:demuxer.streams[1].codecpar});

    let videoFilter = await _getVideoFilter({width:582,height:800}, {width:320, height:240});

    let audioCount = 0, videoCount = 0;
    let packet = {};
    for ( let x = 0 ; x < 100 && packet != null ; x++ ) {
        packet = await demuxer.read(); // Read next frame. Note: returns null for EOF
        if (packet) {
            if (packet.stream_index === 0) {
                let frames = await videoDecoder.decode(packet);

                let filteredData = await parseVideoFrame(videoFilter, frames);
                writeData([filteredData], 'test.rgba');
                return;

                console.log(x, `收到视频帧，frameLength:${frames.frames.length}, total_time:${frames.total_time}`);
                videoCount++;
            }
        }
    }
    console.log(`===================================`);
    console.log(`videoCount:${videoCount}, audioCount:${audioCount}`);

    let frames = await videoDecoder.flush(); // Must tell the videoDecoder when we are done
    console.log('flush', frames.total_time, frames.length);
}

run();